package com.kmist.xiakexing.presenters;

import android.util.Log;

import com.kmist.xiakexing.data.IPlayerDaoCallback;
import com.kmist.xiakexing.data.PlayerDao;
import com.kmist.xiakexing.interfaces.IPlayerCallback;
import com.kmist.xiakexing.interfaces.IPlayerPresenter;
import com.kmist.xiakexing.main.socket.DataRecver;
import com.kmist.xiakexing.main.socket.DataSender;
import com.kmist.xiakexing.main.socket.ISocketCallback;
import com.kmist.xiakexing.main.socket.SockPresenter;
import com.kmist.xiakexing.main.socket.cmd;
import com.kmist.xiakexing.main.socket.retCode;
import com.kmist.xiakexing.tools.Config;
import com.kmist.xiakexing.tools.MD5;
import com.kmist.xiakexing.utils.scene.PlayerBean;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.annotations.NonNull;
import io.reactivex.schedulers.Schedulers;

public class PlayerPresenter implements IPlayerPresenter, IPlayerDaoCallback, ISocketCallback {

    private final PlayerDao playerDao;
    private final SockPresenter sockPresenter;
    private static PlayerPresenter sInstance;
    private final List<IPlayerCallback> playerCallbacks = new ArrayList<>();

    private String sid;
    private PlayerBean player;

    public static PlayerPresenter getInstance() {
        if (sInstance == null) {
            synchronized (PlayerPresenter.class){
                sInstance = new PlayerPresenter();
            }
        }
        return sInstance;
    }

    public PlayerPresenter() {
        player = new PlayerBean();
        sockPresenter = SockPresenter.getInstance();
        sockPresenter.setCallback(this);
        playerDao = PlayerDao.getsInstance();
        playerDao.setCallback(this);
    }

    @Override
    public void setPlayerDefaultConfig(PlayerBean playerBean) {
        playerBean.setUlv(1);
        playerBean.setUyxb(100);
        playerBean.setUexp(100);
        playerBean.setUhp(100);
        playerBean.setUmaxhp(100);
        playerBean.setUgj(15);
        playerBean.setUfy(5);
        playerBean.setUwx(0);
        playerBean.setVip(0);
        playerBean.setNowmid(255);
        playerBean.setEndtime(Config.data());
        playerBean.setSfzx(1);
    }

    @Override
    public String calPlayerSid(String userName, String token) {
        return MD5.md5(userName+token+"229");
    }

    @Override
    public void addPlayer(PlayerBean playerBean) {
        Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<Object> emitter) throws Exception {
                //只调用，不处理结果
                if (playerDao != null) {
                    playerDao.addPlayer(playerBean);
                }
            }
        }).subscribeOn(Schedulers.io()).subscribe();
    }

    @Override
    public void delPlayer(PlayerBean playerBean) {
        Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<Object> emitter) throws Exception {
                if (playerDao != null) {
                    playerDao.delPlayer(playerBean);
                }
            }
        }).subscribeOn(Schedulers.io()).subscribe();
    }

    @Override
    public void getPlayer() {
       try {
           JSONObject jsonObject = Config.val2json("sid", sid);
           if(sid != null){
               DataSender info = new DataSender(cmd.CMD_PLAYER_GETPLAYER, jsonObject.toString());
               sockPresenter.sendMessage(info.toString());
           }
       } catch (Exception e) {
           e.printStackTrace();
       }
    }

    @Override
    public void updateOnlineLastTime() {

        JSONObject jsonObject = Config.val2json("sid", player.getSid());
        DataSender info = new DataSender(cmd.CMD_PLAYER_UPDATEENDTIME, jsonObject.toString());
        sockPresenter.sendMessage(info.toString());
    }

    @Override
    public void getmapPlayer(int mapid) {
        JSONObject jsonObject = Config.val2json("mid", mapid);
        if(jsonObject != null){
            DataSender info = new DataSender(cmd.CMD_PLAYER_GETMAPPLAYER, jsonObject.toString());
            sockPresenter.sendMessage(info.toString());
        }
    }

    @Override
    public PlayerBean getPlayerd() {
        return player;
    }

    @Override
    public boolean isPlayerExist(String sid) {
        return false;
    }

    @Override
    public void changeExp(String sid, int exp) {
        Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<Object> emitter) throws Exception {
                //只调用，不处理结果
                if (playerDao != null) {
                    playerDao.getPlayer(sid);
                }
            }
        }).subscribeOn(Schedulers.io()).subscribe();
    }

    @Override
    public void setPlayerSid(String sid) {
        if (player != null) {
            player.setSid(sid);
        }
        this.sid = sid;
    }

    @Override
    public String getPlayerSid() {
        return sid;
    }

    @Override
    public int getNowmid() {
        if (player != null) {
            return player.getNowmid();
        }
        return 0;
    }

    @Override
    public void changePlayerSx(String mibName, String mibValue, String sid) {
        try {

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("mibName", mibName);
            jsonObject.put("mibValue", mibValue);
            jsonObject.put("sid", sid);

            DataSender info = new DataSender(cmd.CMD_PLAYER_UPDATESHUXING, jsonObject.toString());
            if(info.toString().length() > 100){
                info.setSendLength(info.toString().length()+1);
            }else{
                info.setSendLength(info.toString().length());
            }
            sockPresenter.sendMessage(info.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onPlayerAdded() {
        for (IPlayerCallback callback : playerCallbacks) {
            callback.onPlayerAdded();
        }
    }

    @Override
    public void onPlayerAddError() {
        for (IPlayerCallback callback : playerCallbacks) {
            callback.onPlayerAddError();
        }
    }

    @Override
    public void onPlayerDeled() {
        for (IPlayerCallback callback : playerCallbacks) {
            callback.onPlayerDeled();
        }
    }

    @Override
    public void onPlayerDelError() {
        for (IPlayerCallback callback : playerCallbacks) {
            callback.onPlayerDelError();
        }
    }

    @Override
    public void onPlayerLoaded(PlayerBean playerBean) {
        this.player = playerBean;
        for (IPlayerCallback callback : playerCallbacks) {
            callback.onPlayerLoaded(playerBean);
        }
    }

    @Override
    public void onPlayerLoadErr() {
        for (IPlayerCallback callback : playerCallbacks) {
            callback.onPlayerLoadErr();
        }
    }

    @Override
    public void onPlayerLoadEmpty() {
        for (IPlayerCallback callback : playerCallbacks) {
            callback.onPlayerLoadEmpty();
        }
    }

    @Override
    public void onPlayerUpdateOK() {
        for (IPlayerCallback callback : playerCallbacks) {
            callback.onPlayerUpdateOk();
        }
    }

    @Override
    public void onPlayerUpdateErr() {
        for (IPlayerCallback callback : playerCallbacks) {
            callback.onPlayerUpdateErr();
        }
    }

    @Override
    public void registerViewCallback(IPlayerCallback callback) {
        if(!playerCallbacks.contains(callback)){
            playerCallbacks.add(callback);
        }
    }

    @Override
    public void unRegisterViewCallback(IPlayerCallback callback) {
        playerCallbacks.remove(callback);
    }

    @Override
    public void onConnected() {
        //no deal
    }

    @Override
    public void onNetworkError() {

    }

    @Override
    public void onDataRecved(DataRecver dataRecver) {
        if (!dataRecver.getResp_cmd().substring(0,2).equals(cmd.CMD_PLAYER)) {
            return;
        }


        switch (dataRecver.getResp_code()){
            case retCode.RET_OK:{
                if(dataRecver.getResp_cmd().equals(cmd.CMD_PLAYER_GETPLAYER)){

                    getPlayerMsg(dataRecver.getResp_data());
                }else if(dataRecver.getResp_cmd().equals(cmd.CMD_PLAYER_GETMAPPLAYER)){

                    //getMapPlayerMsg(dataRecver.getResp_data());
                }else{
                    Log.d("RECV:"," 操作成功！");
                }
            } break;
            case retCode.ERRCD_NOACCOUNT:
                Log.d("RECV:",""+dataRecver.getResp_code());
                break;
        }
    }

    private void getPlayerMsg(String resp_data) {
        try {
            JSONObject jroot = new JSONObject(resp_data);
            String playerVal = jroot.getString("player");
            JSONObject tmproot = new JSONObject(playerVal);

            player.setUid(tmproot.getString("uid"));
            player.setSid(tmproot.getString("sid"));
            player.setUname(tmproot.getString("uname"));
            player.setUlv(tmproot.getInt("ulv"));
            player.setUyxb(tmproot.getInt("uyxb"));
            player.setUczb(tmproot.getInt("uczb"));
            player.setUexp(tmproot.getInt("uexp"));
            player.setUmaxexp(tmproot.getInt("umaxexp"));
            player.setUhp(tmproot.getInt("uhp"));
            player.setUmaxhp(tmproot.getInt("umaxhp"));
            player.setUgj(tmproot.getInt("ugj"));
            player.setUfy(tmproot.getInt("ufy"));
            player.setUbj(tmproot.getInt("ubj"));
            player.setUxx(tmproot.getInt("uxx"));
            player.setUwx(tmproot.getInt("uwx"));
            player.setUsex(tmproot.getString("usex"));
            player.setTool1(tmproot.getInt("tool1"));
            player.setTool2(tmproot.getInt("tool2"));
            player.setTool3(tmproot.getInt("tool3"));
            player.setTool4(tmproot.getInt("tool4"));
            player.setTool5(tmproot.getInt("tool5"));
            player.setTool6(tmproot.getInt("tool6"));
            player.setYp1(tmproot.getInt("yp1"));
            player.setYp2(tmproot.getInt("yp2"));
            player.setYp3(tmproot.getInt("yp3"));
            player.setJn1(tmproot.getInt("jn1"));
            player.setJn2(tmproot.getInt("jn2"));
            player.setJn3(tmproot.getInt("jn3"));
            player.setJingjie(tmproot.getString("jingjie"));
            player.setSfxl(tmproot.getInt("sfxl"));
            player.setSfzx(tmproot.getInt("sfzx"));
            player.setIspvp(tmproot.getInt("ispvp"));
            player.setVip(tmproot.getInt("vip"));
            player.setNowmid(tmproot.getInt("nowmid"));
            player.setEndtime(tmproot.getString("endtime"));
            player.setCw(tmproot.getInt("cw"));

            for (IPlayerCallback callback : playerCallbacks) {
                callback.onPlayerLoaded(player);
            }
        } catch (Exception e) {
            for (IPlayerCallback callback : playerCallbacks) {
                callback.onPlayerLoadErr();
            }
            e.printStackTrace();
        }
    }
}
